﻿using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using TFSTools.TFSLibrary;
using TFSTools.TFSLibrary.TestManagement;

namespace TFSTools.TestManagement.TestCaseReview
{
    /// <summary>
    /// Interaction logic for MainView
    /// </summary>
    public partial class MainView : Window
    {
        #region Data Members

        private TFSConnection connection = null;
        private string stepCommentFieldReferenceName = string.Empty;
        private TFSTestPlan testPlan = null;
        private bool isFirstTimeActivated = false;

        private Dictionary<int, TestCaseView> openTestCases = new Dictionary<int, TestCaseView>();

        #endregion

        #region Constructor

        public MainView()
        {
            this.InitializeComponent();

            //var settings = Properties.Settings.Default;
            //settings.TfsUri = "";
            //settings.TestPlanId = -1;
            //settings.TestProject = "";
            //settings.IncludeParameterNameInIterationText = true;
            //settings.DefaultStepCommentFieldReferenceName = "TFSTools.StepComments";
            //settings.StepCommentFieldReferenceNames = string.Empty;
            //settings.Save();
        }

        #endregion

        #region Window Events

        private void Window_Activated(object sender, EventArgs e)
        {
            if (this.isFirstTimeActivated)
            {
                return;
            }

            this.isFirstTimeActivated = true;

            this.LoadServerFromSettings();
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            foreach (var openWindow in this.openTestCases)
            {
                openWindow.Value.Close();
            }
        }

        private void ConnectButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                TestPlanView testPlanView = null;

                using (new WaitCursorHelper(this))
                {
                    testPlanView = new TestPlanView(this.connection);
                    testPlanView.SelectedTestPlan = this.testPlan;
                    testPlanView.Owner = this;
                }

                var result = testPlanView.ShowDialog();

                if (result == true)
                {
                    if (this.connection == null)
                    {
                        this.connection = testPlanView.Connection;
                    }

                    this.UpdateTestPlan(testPlanView.SelectedTestPlan);
                }

                this.SetServerInfoText(string.Empty);
            }
            catch (Exception ex)
            {
                MessageBox.Show("An error occured.  " + ex.Message);
            }
        }

        private void ConfigureButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                var optionsWindow = new OptionsWindow();
                optionsWindow.ViewDataContext = new OptionsDataContext(this.connection);
                optionsWindow.ShowDialog();
            }
            catch (Exception ex)
            {
                MessageBox.Show("An error occured.  " + ex.Message);
            }
        }

        private void RefreshButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                this.treeSuites.Items.Clear();
                this.dgWorkItems.ItemsSource = null;

                this.LoadServerFromSettings();
            }
            catch (Exception ex)
            {
                MessageBox.Show("An error occured.  " + ex.Message);
            }
        }

        private void OpenTestCaseButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                System.ComponentModel.BackgroundWorker bw = new System.ComponentModel.BackgroundWorker();

                var selectedItem = dgWorkItems.SelectedItem as TFSWorkItem;

                if (selectedItem != null)
                {
                    if (this.openTestCases.ContainsKey(selectedItem.Id))
                    {
                        this.openTestCases[selectedItem.Id].Activate();
                    }
                    else
                    {
                        TestCaseView testCaseView;

                        using (new WaitCursorHelper(this))
                        {
                            testCaseView = new TestCaseView();
                            var testCase = this.testPlan.TestTeamProject.GetTestCase(selectedItem.Id);
                            testCase.StepCommentsFieldReferenceName = this.stepCommentFieldReferenceName;

                            testCaseView.ViewDataContext = new TestCaseDataContext(testCase, this.testPlan.TestTeamProject);
                        }

                        testCaseView.ShowDialog();
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("An error occured.  " + ex.Message);
            }
        }

        private void TestWorkItemButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                WorkItemTestView view = new WorkItemTestView(this.connection);
                view.ShowDialog();
            }
            catch (Exception ex)
            {
                MessageBox.Show("An error occured.  " + ex.Message);
            }
        }

        private void WorkItemsGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                var selectedItem = dgWorkItems.SelectedItem as TFSWorkItem;

                btnOpenTestCase.IsEnabled = selectedItem != null;
            }
            catch (Exception ex)
            {
                MessageBox.Show("An error occured.  " + ex.Message);
            }
        }

        private void WorkItemsGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            this.OpenTestCaseButton_Click(sender, null);
        }

        private void SuitesTree_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            try
            {
                if (treeSuites.SelectedItem != null)
                {
                    using (new WaitCursorHelper(this))
                    {
                        var tag = ((TreeViewItem)treeSuites.SelectedItem).Tag;
                        TFSWorkItemCollection testCases = null;

                        if (tag is TFSTestSuite)
                        {
                            var testSuite = (TFSTestSuite)tag;
                            testCases = testSuite.GetTestCaseWorkItems(false);
                        }
                        else if (tag.ToString() == "MyTestCases")
                        {
                            testCases = this.testPlan.RootSuite.GetTestCaseWorkItems(true).FilterByAssignedToMe();
                        }

                        if (testCases != null)
                        {
                            dgWorkItems.ItemsSource = WorkItemSorter.Sort(testCases);

                            if (dgWorkItems.Items.Count > 0)
                            {
                                dgWorkItems.SelectedIndex = 0;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("An error occured.  " + ex.Message);
            }
        }

        #endregion

        #region Private Members

        private void LoadServerFromSettings()
        {
            var settings = Properties.Settings.Default;

            try
            {
                if (!string.IsNullOrEmpty(settings.TfsUri) && !string.IsNullOrEmpty(settings.TestProject))
                {
                    if (this.connection == null ||
                        this.connection.ServerUri != settings.TfsUri ||
                        this.connection.SelectedProject == null ||
                        this.connection.SelectedProject.Name != settings.TestProject)
                    {
                        this.SetServerInfoText("Connecting to your Team Project...");

                        this.connection = new TFSConnection(new Uri(settings.TfsUri), settings.TestProject);
                        this.connection.CheckProjectConnection();
                    }

                    if (settings.TestPlanId > 0)
                    {
                        this.SetServerInfoText("Opening Test Plan...");

                        this.UpdateTestPlan(this.connection.TestManagement.TestTeamProject.FindTestPlan(settings.TestPlanId));
                    }
                }

                this.SetServerInfoText(string.Empty);
            }
            catch (Exception ex)
            {
                MessageBox.Show("An error occured.  " + ex.Message);

                settings.TfsUri = string.Empty;
                settings.TestProject = string.Empty;
                this.SetServerInfoText("");
            }
        }

        private void UpdateTestPlan(TFSTestPlan testPlan)
        {
            if (testPlan != null)
            {
                this.testPlan = testPlan;

                this.SetServerInfoText("Retrieving Test Suites...");

                treeSuites.Items.Clear();

                treeSuites.Items.Add(new TreeViewItem()
                                    {
                                        Header = "My Test Cases",
                                        Tag = "MyTestCases",
                                        IsExpanded = false
                                    });

                var builder = new WpfControls.TestSuiteTreeViewItemsBuilder(testPlan)
                {
                    IgnoreSuitesWithoutTestCases = true,
                    IsExpanded = true
                };

                builder.PopulateTreeView(this.treeSuites);
                this.SuitesTree_SelectedItemChanged(this, null);

                var projectSettings = ProjectSettings.GetFromSettings();
                if (projectSettings.ContainsKey(this.TFSConnectionDescription))
                {
                    this.stepCommentFieldReferenceName = projectSettings[this.TFSConnectionDescription].StepCommentFieldReferenceName;
                }
                else
                {
                    this.stepCommentFieldReferenceName = Properties.Settings.Default.DefaultStepCommentFieldReferenceName;
                }

                this.dgWorkItems.ItemsSource = null;
            }
            else
            {
                MessageBox.Show("This team project does not contain any test plans.");
            }

            this.SetServerInfoText(string.Empty);
        }

        private void SetServerInfoText(string text)
        {
            if (string.IsNullOrEmpty(text))
            {
                if (this.connection != null &&
                    this.connection.SelectedProject != null &&
                    this.testPlan != null)
                {
                    tbxTFSServerInfo.Text = TFSConnectionDescription + "; " + this.testPlan.Name;
                }
                else
                {
                    tbxTFSServerInfo.Text = "Click 'Open Test Plan...'";
                }
            }
            else
            {
                tbxTFSServerInfo.Text = text;
            }

            this.Refresh();
            Thread.Sleep(500);
        }

        private string TFSConnectionDescription
        {
            get { return this.connection.ServerName + "; " + this.connection.SelectedProject.Name; }
        }
        #endregion
    }
}
